package pe.com.bbva.modpre.negocio.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.drools.RuleBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import pe.com.bbva.modpre.dominio.AreaCentral;
import pe.com.bbva.modpre.dominio.Cliente;
import pe.com.bbva.modpre.dominio.ClienteGeneral;
import pe.com.bbva.modpre.dominio.CostoFondeo;
import pe.com.bbva.modpre.dominio.CrPe;
import pe.com.bbva.modpre.dominio.EmpresaTop;
import pe.com.bbva.modpre.dominio.ExcepcionDuracionCf;
import pe.com.bbva.modpre.dominio.FacturacionMasivaCarga;
import pe.com.bbva.modpre.dominio.Finanza;
import pe.com.bbva.modpre.dominio.GrupoProducto;
import pe.com.bbva.modpre.dominio.Lista;
import pe.com.bbva.modpre.dominio.MedioPago;
import pe.com.bbva.modpre.dominio.Operacion;
import pe.com.bbva.modpre.dominio.Parametro;
import pe.com.bbva.modpre.dominio.Producto;
import pe.com.bbva.modpre.dominio.Rar;
import pe.com.bbva.modpre.dominio.RiesgoMotor;
import pe.com.bbva.modpre.dominio.Segmento;
import pe.com.bbva.modpre.dominio.Sistema;
import pe.com.bbva.modpre.dominio.TipoBanca;
import pe.com.bbva.modpre.dominio.Usuario;
import pe.com.bbva.modpre.dominio.Valor;
import pe.com.bbva.modpre.dominio.drools.Motor;
import pe.com.bbva.modpre.negocio.CalculoService;
import pe.com.bbva.modpre.persistencia.ExcepcionDuracionCfDAO;
import pe.com.bbva.modpre.utileria.Constante;
import pe.com.bbva.modpre.utileria.ModpreUtil;

@Service
@SuppressWarnings("serial")
public class CalculoServiceImpl extends ConfiguracionServiceImpl implements CalculoService{

	@Autowired
	ExcepcionDuracionCfDAO excepcionDuracionCfDAO;
	
	@Override
	public List<FacturacionMasivaCarga> ejecutarDescargaTEA_RAR(RuleBase ruleBase) {
		List<Motor> lstMotor = new ArrayList<Motor>();
		List<FacturacionMasivaCarga> lstFacturacion=obtenerFacturacionMasivaCarga();
		lstMotor=formarListaTEA_RAR(lstFacturacion,ruleBase);
		correrReglas(ruleBase,  "TEA", lstMotor);  
		
		for (Motor motor : lstMotor) {
			if(motor!=null){
		if(motor.getTasaMinima() != null && motor.getTea().compareTo(motor.getTasaMinima()) == -1) { 
			motor.setTea(motor.getTasaMinima());
		}
		else if(motor.getTasaMaxima() != null && motor.getTea().compareTo(motor.getTasaMaxima()) == 1) { 
			motor.setTea(motor.getTasaMaxima());
		}
			}
		}
		
		this.correrReglas(ruleBase, "ERROR", lstMotor);
		for (Motor motor : lstMotor) {
			if(motor!=null){
			System.out.println("motor BEC TEA " +motor.toString());
			}
		}
		this.formarListaRetornoTEA_RAR(lstFacturacion, lstMotor);
		this.guardarFacturacionMasivaCarga(lstFacturacion);
		return lstFacturacion;
		
	}
	 private void agregarDatosComunes(Motor motor,Operacion operacion,Cliente cliente){
		 Usuario usuario=ModpreUtil.obtenerUsuarioSesion();
		 motor.setCodigoUsuario(usuario.getRegistro());
		 motor.setCodigoCentroCosto(usuario.getOficina());
		 motor.setCodigoProducto(operacion.getProducto().getCodigo());
		 motor.setNombreProducto(operacion.getProducto().getNombre());
		 motor.setNombreCortoProducto(operacion.getProducto().getNombreCorto());
		 motor.setCodigoGrupoProducto(operacion.getProducto().getGrupoProducto().getCodigo());
		 motor.setNombreGrupoProducto(operacion.getProducto().getGrupoProducto().getNombre());
		 motor.setMonto(operacion.getMontoCredito());
		 motor.setCodigoTipoPlazo(operacion.getTipoPlazo().getCodigo());
		 motor.setNombreTipoPlazo(operacion.getTipoPlazo().getNombre());	
		 motor.setCodigoMoneda(operacion.getMoneda().getCodigo());
		 motor.setNombreMoneda(operacion.getMoneda().getNombre());
		 if(cliente.getSegmento()!=null){
			 motor.setCodigoSegmento(cliente.getSegmento().getCodigo());
			 motor.setNombreSegmento(cliente.getSegmento().getNombre());
		 }
	 }
	 
private List<Motor> formarListaTEA_RAR( List<FacturacionMasivaCarga> lstParam, RuleBase ruleBase){
		
		List<Valor> divisaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.DIVISA_CARGA);
		List<Valor> grupoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.GRUPO_PROD_CARGA_RAR);
		List<Valor> montoCargasBEC=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_BEC_RAR);
		List<Valor> scoreVinculadoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.SCORE_VINCULADO);
	
		List<Valor> plazoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.PLAZO_CARGA);
		List<Valor> viviendaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_VIV_DIVISA_CARGA);
		List<Valor> puntajeBuroCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PUNTAJE_BURO_HIP);
		List<Valor> antiguedadCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_ANTIGUEDAD_CARGA);
		List<Valor> ltvCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_LTV_CARGA);
		
		List<Valor> montoCargasHipoRar=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_HIPO_RAR);
		List<Valor> productoCargasHipo=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PROD_CARGA_HIPOT);
		List<Valor> valorClienteCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.VAL_CLIENTE_RAR_MIN);
		
		
		List<Valor> montoCargasConsu=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_CONSU_RAR);
		List<Valor> productoCargasConsu=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PROD_CARGA_CONSU);
		List<Valor> puntajeBuroCargasCon=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PUNTAJE_BURO_CON);
		List<Valor> plazoCrPes=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PLAZO_CONS_CRPE);
		
		Motor motor=null;
		
    	Cliente cliente =null;
    	AreaCentral areaCentral=null;
    	Finanza finanza=null;
    	RiesgoMotor riesgoMotor=null;
    	Sistema sistema=null;
    	TipoBanca tipoBanca=null;    	
    	Segmento segmento=null;
    	MedioPago medioPago =null;
    	Operacion operacion =null;
    	Producto producto= null;
    	GrupoProducto grupoProd=null;
    	ClienteGeneral clienteGeneral=null;
    	List<Motor> lstobject = new ArrayList<Motor>();
    	
        for (FacturacionMasivaCarga paramFac : lstParam) {
        	
        	clienteGeneral=this.obtenerClienteGeneralxCodigoCentral(paramFac.getCodigoCentral());
        	
        	if(clienteGeneral!=null){
        	motor=new Motor();
            cliente = new Cliente();
            tipoBanca=new TipoBanca();
            segmento=new Segmento();
            operacion=new Operacion();
            	
        	cliente.setCodigoCentral(clienteGeneral.getCodigoCentral());
    		areaCentral=this.obtenerAreaCentralCodigoCentral(cliente.getCodigoCentral());
    		finanza=this.obtenerFinanzaCodigoCentral(cliente.getCodigoCentral());
    		riesgoMotor=this.obtenerRiesgoCodigoCentral(cliente.getCodigoCentral());
    		sistema=this.obtenerSistemaCodigoCentral(cliente.getCodigoCentral());
    		medioPago=this.obtenerMedioPagoCodigoCentral(cliente.getCodigoCentral());
    		
    		cliente.setAntiguedadCliente(clienteGeneral.getAntiguedadCliente());
    		segmento.setNombre(clienteGeneral.getSegmento());
    		segmento.setCodigo(clienteGeneral.getCodSegmento());
    		cliente.setSegmento(segmento);
    		
    		producto = productoDAO.obtener(paramFac.getCodigoProducto());
    		operacion.setProducto(producto);
    		operacion.setPlazo(new BigDecimal(paramFac.getPlazoDias()));
    		Valor valor=new Valor();
    		valor.setCodigo(paramFac.getCodMoneda()+"");
    		operacion.setMoneda(valor);
    		operacion.setMontoCredito(paramFac.getMonto());
    		motor.setMoneda(paramFac.getCodMoneda());
        	producto =productoDAO.obtener(paramFac.getCodigoProducto());
			grupoProd=producto.getGrupoProducto();
			motor.setGrupo(Long.parseLong(grupoProd.getCodigo()));
			
			//Consumo
			if(grupoProd.getCodigo().equals("1")){
				motor= this.calcularTeaConsumo(motor, cliente, operacion, areaCentral, finanza, medioPago, 
											riesgoMotor, sistema, clienteGeneral.getNumDoc(), clienteGeneral.getIngresos(),
											tipoBanca, ruleBase,divisaCargas,
											montoCargasConsu, productoCargasConsu, puntajeBuroCargasCon,
											antiguedadCargas, valorClienteCargas, plazoCrPes);
				//Hipotecario
			}else if(grupoProd.getCodigo().equals("2")){
				 motor= this.calcularTeaHipotecario(motor, cliente, operacion, areaCentral, finanza, 
				    								medioPago, riesgoMotor, sistema, clienteGeneral.getNumDoc(),
				    								paramFac.getTipoVivienda(), clienteGeneral.getIngresos(), tipoBanca,  
				    								ruleBase, divisaCargas, montoCargasHipoRar, productoCargasHipo,
				    								plazoCargas, viviendaCargas, puntajeBuroCargas, antiguedadCargas, 
				    								ltvCargas, valorClienteCargas);
			}else{
				//BEC
                motor= this.calcularTeaBEC(motor, clienteGeneral, cliente, operacion, areaCentral, finanza,
		            							medioPago, riesgoMotor, sistema, tipoBanca, segmento, ruleBase, 
		            							divisaCargas, grupoCargas, montoCargasBEC, scoreVinculadoCargas);
		        }
			motor.setSegmentoCliente(clienteGeneral.getSegmento());
			motor.setValorCliente(clienteGeneral.getValorCliente());
			motor.setScoreVinculado(clienteGeneral.getVinculacionCliente());
			motor.setValorComercialActual(clienteGeneral.getValorComercialActial());
			motor.setValorComercialPotencial(clienteGeneral.getValorComercialPotencial());
			
			lstobject.add(motor);
        	}else{
        		lstobject.add(null);
        	}
		}
        return lstobject;
	}

	private List<FacturacionMasivaCarga> formarListaRetornoTEA_RAR(
			List<FacturacionMasivaCarga> lstParam, List<Motor> lstMotor) {
		logger.info(" lstParam " +lstParam.size());
		for (int i = 0; i < lstParam.size(); i++) {
			if(lstMotor.get(i)!=null){
			if (lstMotor.get(i).getValorCliente() != null) {
				lstParam.get(i).setValorCliente(
						lstMotor.get(i).getValorCliente());
			}
			if (lstMotor.get(i).getScoreVinculado() != null) {
				lstParam.get(i).setScoreVinculado(
						lstMotor.get(i).getScoreVinculado());
			}
			if (lstMotor.get(i).getCr() != null) {
				lstParam.get(i).setCr(lstMotor.get(i).getCr());
			}
			if (lstMotor.get(i).getPe() != null) {
				lstParam.get(i).setPe(lstMotor.get(i).getPe());
			}
			if (lstMotor.get(i).getCf() != null) {
				lstParam.get(i).setCostoFondeo(lstMotor.get(i).getCf());
			}
			if (lstMotor.get(i).getCadic() != null) {
				lstParam.get(i).setCadic(lstMotor.get(i).getCadic());
			}
			if (lstMotor.get(i).getComisiones() != null) {
				lstParam.get(i).setComisiones(lstMotor.get(i).getComisiones());
			}
			if (lstMotor.get(i).getTipoImpositivo() != null) {
				lstParam.get(i).setTipoImpositivo(
						lstMotor.get(i).getTipoImpositivo());
			}
			if (lstMotor.get(i).getRatioEficiencia() != null) {
				lstParam.get(i).setRatioEficiencia(
						lstMotor.get(i).getRatioEficiencia());
			}
			if (lstMotor.get(i).getRar() != null) {
				lstParam.get(i).setRar(lstMotor.get(i).getRar());
			}
			if (lstMotor.get(i).getTea() != null) {
				lstParam.get(i).setTea(lstMotor.get(i).getTea());
			}
		 }
		}
		return lstParam;
	}

	public Motor calcularTeaBEC(Motor motor, ClienteGeneral clienteGeneral,
			Cliente cliente, Operacion operacion, AreaCentral areaCentral,
			Finanza finanza, MedioPago medioPago, RiesgoMotor riesgoMotor,
			Sistema sistema, TipoBanca tipoBanca, Segmento segmento,
			RuleBase ruleBase, List<Valor> divisaCargas,
			List<Valor> grupoCargas, List<Valor> montoCargas,
			List<Valor> scoreVinculadoCargas) {

		Valor tipoCarga = valorDAO.obtenerValorxCodigo(Valor.CODIGO.BEC_CARGA);
		Valor estadoActivo = valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if (riesgoMotor != null) {
			motor.setVentasTotales(riesgoMotor.getVentasTotales());
			if (StringUtils.isNotBlank(riesgoMotor.getEscalaRating())) {
				motor.setEscalaRating(riesgoMotor.getEscalaRating());
			} else {
				motor.setEscalaRating(Constante.NB_ESCALARATING);
			}

		} else {
			motor.setEscalaRating(Constante.NB_ESCALARATING);
		}
		if (areaCentral != null) {
			motor.setCantidadFamiliaProductos(areaCentral.getCantFramProd());
		}
		if (sistema != null) {
			motor.setFlujoPagoProveedores(sistema.getFlujoPagoProvee());
			motor.setFlujoPagoHaberes(sistema.getFlujoPagoHaberes());
		}
		if (finanza != null) {
			motor.setMargenTotal(finanza.getMargenTotal());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
		}

		if (segmento != null) {
			motor.setSegmentoCliente(segmento.getNombre());
		}
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		BigDecimal plazoDias = operacion.getPlazo();

		obtenerMoneda(motor, operacion, divisaCargas);
		obtenerGrupo(motor, operacion, grupoCargas);
		obtenerMonto(motor, operacion, montoCargas);

		motor.setValorCliente(clienteGeneral.getValorCliente());
		motor.setScoreVinculado(clienteGeneral.getVinculacionCliente());
		motor.setValorComercialActual(clienteGeneral.getValorComercialActial());
		motor.setValorComercialPotencial(clienteGeneral
				.getValorComercialPotencial());
		// correrRegla

		obtenerScoreVinculado(motor, scoreVinculadoCargas);

		motor.setValorClienteRar(motor.getValorCliente());

		Rar rar = new Rar();
		rar.setCodigoMoneda(motor.getMoneda());
		rar.setCodigoGrupoProducto(motor.getGrupo());
		rar.setValorCliente(motor.getValorClienteRar());
		rar.setScoreVinculado(motor.getScoreVinculadoRar());
		rar.setCodigoMonto(motor.getMontoAgrupado());
		rar.setTipoCarga(tipoCarga);
		rar.setEstado(estadoActivo);
		rar = rarDAO.obtenerRar(rar);
		System.out.println("rar " + rar);
		if (rar != null) {
			motor.setTasaMinima(rar.getTasaMinima());
			motor.setTasaMaxima(rar.getTasaMaxima());
			motor.setRar(rar.getRarocPropuesto());
			motor.setPuntoOptimo(rar.getPuntoOptimo());
		}
		CrPe crPe = null;
		if (StringUtils.isNotBlank(motor.getEscalaRating())) {
			crPe = new CrPe();
			crPe.setEscalaRating(motor.getEscalaRating());
			crPe.setTipoCarga(tipoCarga);
			crPe.setEstado(estadoActivo);
			crPe = crPeDAO.obtenerCrPe(crPe);
		}

		if (crPe != null) {
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		} else {
			motor.setCr(BigDecimal.ZERO);
			motor.setPe(BigDecimal.ZERO);
		}

		ExcepcionDuracionCf excepcionDuracionCf = new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto()
				.getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf = excepcionDuracionCfDAO
				.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo = new CostoFondeo();
		if (excepcionDuracionCf != null) {
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf
					.getAsignarPlazo());
			motor.setPlazoCf(excepcionDuracionCf.getAsignarPlazo());
		} else {
			costoFondeo.setCantidadDiasMaximo(plazoDias);
			motor.setPlazoCf(plazoDias);
		}
		costoFondeo = costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if (costoFondeo != null) {
			motor.setFechaCf(costoFondeo.getFecha());
			if (operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)) {
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			} else {
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}

		return motor;
	}

	public Motor calcularTeaConsumo(Motor motor, Cliente cliente,
			Operacion operacion, AreaCentral areaCentral, Finanza finanza,
			MedioPago medioPago, RiesgoMotor riesgoMotor, Sistema sistema,
			String ruc, BigDecimal ingreso, TipoBanca tipoBanca,
			RuleBase ruleBase, List<Valor> divisaCargas,
			List<Valor> montoCargas, List<Valor> productoCargas,
			List<Valor> puntajeBuroCargas, List<Valor> antiguedadCargas,
			List<Valor> valorClienteCargas, List<Valor> plazoCrPes) {

		Valor tipoCarga = valorDAO
				.obtenerValorxCodigo(Valor.CODIGO.CONSUMO_CARGA);
		Valor estadoActivo = valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if (finanza != null) {
			motor.setMargenOrdinario(finanza.getMargenOrd());
			motor.setSaldoMedioActivo(finanza.getSaldoMedioAct());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
			motor.setSpreadHipotecario(finanza.getSpreadHipo());
			motor.setSpreadConsumo(finanza.getSpreadCon());
		}
		if (sistema != null) {
			if (sistema.getEsPagoHabiente().equalsIgnoreCase("S")) {
				motor.setEsPagoHabiente(true);
			} else {
				motor.setEsPagoHabiente(false);
			}
		}
		if (areaCentral != null) {
			motor.setDeudaHipotecaria(areaCentral.getDeudaHipoBbva().add(
					areaCentral.getDeudaHipoOtros()));
			motor.setDeudaConsumo(areaCentral.getDeudaConsBbva().add(
					areaCentral.getDeudaConsOtros()));
			motor.setCuotaRiesgo(areaCentral.getCuotaRiesgoTotal());
			motor.setHipotecario(areaCentral.getDeudaHipoBbva());
			motor.setConsumo(areaCentral.getDeudaConsBbva());
			motor.setTarjetaCredito(areaCentral.getDeudaTarjBbva());
		}
		if (medioPago != null) {
			motor.setLineaMaximaTarjetaCredito(medioPago.getLineaMaxTcBbva());
			motor.setSpreadTarjetaCredito(medioPago.getSpreadTc());
		}
		if (cliente != null) {
			motor.setUbigeoDireccionCliente(cliente.getUbigeoCliente());
		}

		motor.setIngreso(ingreso);

		EmpresaTop empresaTop = empresaTopDAO.obtenerEmpresaTopxRuc(ruc);
		if (empresaTop == null) {
			motor.setEsRepresentanteTop(false);
		} else {
			motor.setEsRepresentanteTop(true);
		}
		motor.setPeso(operacion.getProducto().getPeso());
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		motor.setPlazo(operacion.getPlazo());

		BigDecimal plazoDias = operacion.getPlazo();

		obtenerMoneda(motor, operacion, divisaCargas);

		obtenerGrupo(motor, operacion, productoCargas);

		obtenerMontoConsumo(motor, operacion, montoCargas);

		obtenerPuntajeBuroConsumo(motor, riesgoMotor, puntajeBuroCargas);

		obtenerPlazoCrPE(motor, plazoDias, plazoCrPes);

		obtenerAntiguedad(motor, cliente, antiguedadCargas);

		this.correrReglas(ruleBase, motor, "Margen Mix");
		this.correrReglas(ruleBase, motor, "Valor Comercial Actual Consumo");
		this.correrReglas(ruleBase, motor, "Valor Comercial Potencial Consumo");
		this.correrReglas(ruleBase, motor, "Valor Cliente Consumo");

		obtenerValorCliente(motor, valorClienteCargas);

		Rar rar = new Rar();
		rar.setCodigoGrupoProducto(motor.getGrupo());
		rar.setCodigoMoneda(motor.getMoneda());
		rar.setCodigoMonto(motor.getMontoAgrupado());
		rar.setValorCliente(motor.getValorClienteRar());
		rar.setTipoCarga(tipoCarga);
		rar.setEstado(estadoActivo);
		rar = rarDAO.obtenerRar(rar);

		if (rar != null) {
			motor.setTasaMinima(rar.getTasaMinima());
			motor.setTasaMaxima(rar.getTasaMaxima());
			motor.setRar(rar.getRar());
			motor.setPuntoOptimo(rar.getPuntoOptimo());
		}

		CrPe crPe = null;
		if (motor.getPuntajeBuro() != null
				&& motor.getAntiguedadCliente() != null) {
			crPe = new CrPe();
			crPe.setCodigoProducto(motor.getGrupo());
			crPe.setCodigoPuntajeBuro(motor.getPuntajeBuro().longValueExact());
			crPe.setCodigoAntiguedadCliente(motor.getAntiguedadCliente()
					.longValueExact());
			crPe.setTipoCarga(tipoCarga);
			crPe.setCodigoPlazo(motor.getPlazoCrPe().longValueExact());
			crPe.setEstado(estadoActivo);
			crPe = crPeDAO.obtenerCrPe(crPe);
		}

		if (crPe != null) {
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		} else {
			motor.setCr(BigDecimal.ZERO);
			motor.setPe(BigDecimal.ZERO);
		}

		ExcepcionDuracionCf excepcionDuracionCf = new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto()
				.getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf = excepcionDuracionCfDAO
				.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo = new CostoFondeo();
		if (excepcionDuracionCf != null) {
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf
					.getAsignarPlazo());
			motor.setPlazoCf(excepcionDuracionCf.getAsignarPlazo());
		} else {
			costoFondeo.setCantidadDiasMaximo(plazoDias);
			motor.setPlazoCf(plazoDias);
		}
		costoFondeo = costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if (costoFondeo != null) {
			motor.setFechaCf(costoFondeo.getFecha());
			if (operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)) {
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			} else {
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}

		return motor;
	}

	public Motor calcularTeaHipotecario(Motor motor, Cliente cliente,
			Operacion operacion, AreaCentral areaCentral, Finanza finanza,
			MedioPago medioPago, RiesgoMotor riesgoMotor, Sistema sistema,
			String ruc, String tipoVivienda, BigDecimal ingreso,
			TipoBanca tipoBanca, RuleBase ruleBase, List<Valor> divisaCargas,
			List<Valor> montoCargas, List<Valor> productoCargas,
			List<Valor> plazoCargas, List<Valor> viviendaCargas,
			List<Valor> puntajeBuroCargas, List<Valor> antiguedadCargas,
			List<Valor> ltvCargas, List<Valor> valorClienteCargas) {

		Valor tipoCarga = valorDAO
				.obtenerValorxCodigo(Valor.CODIGO.HIPOTECARIO_CARGA);
		Valor estadoActivo = valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if (finanza != null) {
			motor.setMargenOrdinario(finanza.getMargenOrd());
			motor.setSaldoMedioActivo(finanza.getSaldoMedioAct());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
			motor.setSpreadConsumo(finanza.getSpreadCon());
			motor.setSpreadHipotecario(finanza.getSpreadHipo());
		}
		if (sistema != null) {
			if (sistema.getEsPagoHabiente().equalsIgnoreCase("S")) {
				motor.setEsPagoHabiente(true);
			} else {
				motor.setEsPagoHabiente(false);
			}
		}
		if (areaCentral != null) {
			motor.setCuotaRiesgo(areaCentral.getCuotaRiesgoTotal());
			motor.setDeudaHipotecaria(areaCentral.getDeudaHipoBbva().add(
					areaCentral.getDeudaHipoOtros()));
			motor.setDeudaConsumo(areaCentral.getDeudaConsBbva().add(
					areaCentral.getDeudaConsOtros()));
			motor.setHipotecario(areaCentral.getDeudaHipoBbva());
			motor.setConsumo(areaCentral.getDeudaConsBbva());
			motor.setTarjetaCredito(areaCentral.getDeudaTarjBbva());
		}
		if (medioPago != null) {
			motor.setLineaMaximaTarjetaCredito(medioPago.getLineaMaxTcBbva());
			motor.setSpreadTarjetaCredito(medioPago.getSpreadTc());
		}
		if (cliente != null) {
			motor.setUbigeoDireccionCliente(cliente.getUbigeoCliente());
		}

		motor.setIngreso(ingreso);

		EmpresaTop empresaTop = empresaTopDAO.obtenerEmpresaTopxRuc(ruc);
		if (empresaTop == null) {
			motor.setEsRepresentanteTop(false);
		} else {
			motor.setEsRepresentanteTop(true);
		}
		motor.setPeso(operacion.getProducto().getPeso());
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());

		obtenerMoneda(motor, operacion, divisaCargas);

		obtenerGrupo(motor, operacion, productoCargas);

		obtenerMontoHipotecario(motor, operacion, montoCargas);

		BigDecimal plazoDias = operacion.getPlazo();

		obtenerPlazo(motor, plazoDias, plazoCargas);

		obtenerPuntajeBuro(motor, riesgoMotor, puntajeBuroCargas);

		obtenerAntiguedad(motor, cliente, antiguedadCargas);

		obtenerCodigoVivienda(motor, tipoVivienda, viviendaCargas);

		// obtenerCodigoLtv(motor, operacion, ltvCargas);

		this.correrReglas(ruleBase, motor, "Margen Mix");
		this.correrReglas(ruleBase, motor, "Valor Comercial Actual Hipotecario");
		this.correrReglas(ruleBase, motor,
				"Valor Comercial Potencial Hipotecario");
		this.correrReglas(ruleBase, motor, "Valor Cliente Hipotecario");

		obtenerValorCliente(motor, valorClienteCargas);

		Rar rar = new Rar();
		rar.setCodigoGrupoProducto(motor.getGrupo());
		rar.setCodigoMoneda(motor.getMoneda());
		rar.setCodigoMonto(motor.getMontoAgrupado());
		rar.setCodigoPlazo(motor.getPlazo().longValueExact());
		rar.setValorCliente(motor.getValorClienteRar());
		rar.setTipoCarga(tipoCarga);
		rar.setEstado(estadoActivo);
		rar = rarDAO.obtenerRar(rar);

		if (rar != null) {
			motor.setTasaMinima(rar.getTasaMinima());
			motor.setTasaMaxima(rar.getTasaMaxima());
			motor.setRar(rar.getRar());
			motor.setPuntoOptimo(rar.getPuntoOptimo());
		}

		CrPe crPe = null;
		if (motor.getPuntajeBuro() != null
				&& motor.getAntiguedadCliente() != null) {
			crPe = new CrPe();
			crPe.setCodigoProducto(motor.getGrupo());
			crPe.setCodigoPuntajeBuro(motor.getPuntajeBuro().longValueExact());
			crPe.setCodigoAntiguedadCliente(motor.getAntiguedadCliente()
					.longValueExact());
			crPe.setCodigoDivisa(motor.getMoneda());
			crPe.setCodigoViviendaDivisa(motor.getCodigoViviendaDivisa());
			crPe.setCodigoLtv(motor.getCodigoLtv());
			crPe.setTipoCarga(tipoCarga);
			crPe.setEstado(estadoActivo);
			crPe = crPeDAO.obtenerCrPe(crPe);
		}

		if (crPe != null) {
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		} else {
			motor.setCr(BigDecimal.ZERO);
			motor.setPe(BigDecimal.ZERO);
		}

		ExcepcionDuracionCf excepcionDuracionCf = new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto()
				.getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf = excepcionDuracionCfDAO
				.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo = new CostoFondeo();
		if (excepcionDuracionCf != null) {
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf
					.getAsignarPlazo());
			motor.setPlazoCf(excepcionDuracionCf.getAsignarPlazo());
		} else {
			costoFondeo.setCantidadDiasMaximo(plazoDias);
			motor.setPlazoCf(plazoDias);
		}
		costoFondeo = costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if (costoFondeo != null) {
			motor.setFechaCf(costoFondeo.getFecha());
			if (operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)) {
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			} else {
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}

		return motor;
	}

	private void obtenerCodigoVivienda(Motor motor, String tipoVivienda,List<Valor> viviendaCargas) {
		BigDecimal codigoVivienda;
		if (tipoVivienda.equals("Si")) {
			codigoVivienda = new BigDecimal("1");
		} else {
			codigoVivienda = new BigDecimal("2");
		}
		for (Valor vivienda : viviendaCargas) {
			if (ModpreUtil.esIgual(codigoVivienda, vivienda.getAux1())
					&& ModpreUtil.esIgual(new BigDecimal(motor.getMoneda()),
							vivienda.getAux2())) {
				motor.setCodigoViviendaDivisa(Long.parseLong(vivienda
						.getCodigo()));
				break;
			}
		}
	}
/********************************************* FIN DESCARGA MASICA TEA RAR *****************************************************/


	public List<ClienteGeneral> ejecutarDescargaSVSC(RuleBase ruleBase) {
		List<Valor> scoreVinculadoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.SCORE_VINCULADO);
		List<Motor> lstMotor = new ArrayList<Motor>();
		List<ClienteGeneral> lstParam = new ArrayList<ClienteGeneral>();
		lstParam=obtenerClientesGenerales();
		lstMotor=this.formarLista(lstParam,ruleBase);
		
		this.correrReglas(ruleBase, "Valor Cliente BEC", lstMotor);	  
		this.correrReglas(ruleBase, "Flujo Pago Proveedores", lstMotor); 
		this.correrReglas(ruleBase, "Margen Total", lstMotor);           
		this.correrReglas(ruleBase, "Flujo Pago Haberes", lstMotor);	  
		this.correrReglas(ruleBase, "Saldo Medio Pasivo", lstMotor);    
		
		for (Motor motor : lstMotor) {
			obtenerScoreVinculado(motor, scoreVinculadoCargas);
			motor.setValorClienteRar(motor.getValorCliente());
			//System.out.println("motor BEC " +motor.toString());
		}
		
		correrReglas(ruleBase,  "Margen Mix", lstMotor);
		correrReglas(ruleBase, "Valor Comercial Actual Hipotecario", lstMotor);
		correrReglas(ruleBase, "Valor Comercial Potencial Hipotecario", lstMotor);
		correrReglas(ruleBase,  "Valor Cliente Hipotecario", lstMotor);
		
		this.correrReglas(ruleBase, "ERROR", lstMotor);
		
		List<Valor> valorClienteCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.VAL_CLIENTE_RAR_MIN);
		for (Motor motor : lstMotor) {
			obtenerValorCliente(motor, valorClienteCargas);
		    System.out.println("motor PAR " +motor.toString());
		}
		
		this.formarListaRetorno(lstParam, lstMotor);
		
		for (ClienteGeneral cliente : lstParam) {
        	if(cliente.getTipoDoc().equals("R")){
        	cliente.setValorComercialActial(null);
        	cliente.setValorComercialPotencial(null);
        	}else{
        		cliente.setVinculacionCliente(null);
        	}
	   }
		
		guardarClientesGenerales(lstParam);
		//lstParam=obtenerClientesGenerales();
		return lstParam;
	}
	
	 private List<ClienteGeneral> formarListaRetorno( List<ClienteGeneral> lstParam, List<Motor> lstMotor){
		for (int i = 0; i < lstParam.size(); i++) {

			if (lstMotor.get(i).getValorCliente() != null) {
				lstParam.get(i).setValorCliente(
						lstMotor.get(i).getValorCliente());
			}
			if (lstMotor.get(i).getScoreVinculado() != null) {
				lstParam.get(i).setVinculacionCliente(
						lstMotor.get(i).getScoreVinculado());
			}
			if (lstMotor.get(i).getValorComercialActual() != null) {
				lstParam.get(i).setValorComercialActial(
						lstMotor.get(i).getValorComercialActual());
			}
			if (lstMotor.get(i).getValorComercialPotencial() != null) {
				lstParam.get(i).setValorComercialPotencial(
						lstMotor.get(i).getValorComercialPotencial());
			}
		}
		 return lstParam;
	 }
	private List<Motor> formarLista( List<ClienteGeneral> lstParam, RuleBase ruleBase){
		List<Valor> divisaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.DIVISA_CARGA);
		List<Valor> grupoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.GRUPO_PROD_CARGA_RAR);
		List<Valor> montoCargasBec=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_BEC_RAR);
		List<Valor> puntajeBuroCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PUNTAJE_BURO_HIP);
		List<Valor> antiguedadCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_ANTIGUEDAD_CARGA);
		BigDecimal peso = ModpreUtil.convertirObjetoBigDecimal(parametroDAO.obtenerParametroxCodigo(Parametro.CODIGO.PESO_VC).getValor());
		
		Motor motor=null;
		
    	Cliente cliente =null;
    	AreaCentral areaCentral=null;
    	Finanza finanza=null;
    	RiesgoMotor riesgoMotor=null;
    	Sistema sistema=null;
    	TipoBanca tipoBanca=null;    	
    	Segmento segmento=null;
    	MedioPago medioPago =null;
    	List<Motor> lstobject = new ArrayList<Motor>();
    	
        for (ClienteGeneral paramGen : lstParam) {
        	
        	cliente = new Cliente();
        	tipoBanca=new TipoBanca();
        	segmento=new Segmento();
        	
        	motor=new Motor();
    		cliente.setCodigoCentral(paramGen.getCodigoCentral());
    		cliente.setAntiguedadCliente(paramGen.getAntiguedadCliente());
    		cliente.setUbigeoCliente(paramGen.getUbigeo());
    		segmento.setNombre(paramGen.getSegmento());
    		
    		areaCentral=this.obtenerAreaCentralCodigoCentral(cliente.getCodigoCentral());
    		finanza=this.obtenerFinanzaCodigoCentral(cliente.getCodigoCentral());
    		riesgoMotor=this.obtenerRiesgoCodigoCentral(cliente.getCodigoCentral());
    		sistema=this.obtenerSistemaCodigoCentral(cliente.getCodigoCentral());
    		medioPago=this.obtenerMedioPagoCodigoCentral(cliente.getCodigoCentral());
    		
    		if(paramGen.getTipoDoc().equals("R")){
    			
    		tipoBanca.setCodigo(TipoBanca.CODIGO.TIPO_BEC);
            motor= this.hallarMotorBEC (motor, cliente, areaCentral,
            		                        finanza, riesgoMotor, sistema,
            		                        tipoBanca, segmento, ruleBase,
            		                         divisaCargas,
            		                         grupoCargas,montoCargasBec);
            
            
            }else {
            tipoBanca.setCodigo(TipoBanca.CODIGO.TIPO_MINORISTA);	
            motor = this.hallarMotorParticular(motor, cliente, areaCentral, finanza,
            						medioPago, riesgoMotor, sistema, 
            						paramGen.getNumDoc(), paramGen.getIngresos(), tipoBanca, ruleBase,peso);
           
       
    		
    		obtenerPuntajeBuro(motor, riesgoMotor, puntajeBuroCargas);
    		
    		obtenerAntiguedad(motor, cliente, antiguedadCargas);
    		
            }
            
        	lstobject.add(motor);
		}
        return lstobject;
	}
	
	private Motor hallarMotorBEC(Motor motor,Cliente cliente , AreaCentral areaCentral, Finanza finanza, 
			RiesgoMotor riesgoMotor, Sistema sistema,TipoBanca tipoBanca, Segmento segmento,RuleBase ruleBase,
			List<Valor> divisaCargas, List<Valor> grupoCargas, List<Valor> montoCargas){

		motor.setTipoBanca(tipoBanca);
		if(riesgoMotor!=null){
			motor.setVentasTotales(riesgoMotor.getVentasTotales());
			if(StringUtils.isNotBlank(riesgoMotor.getEscalaRating())){
				motor.setEscalaRating(riesgoMotor.getEscalaRating());	
			}else{
				motor.setEscalaRating(Constante.NB_ESCALARATING);
			}
					
		}else{
			motor.setEscalaRating(Constante.NB_ESCALARATING);
		}
		if(areaCentral!=null){
			motor.setCantidadFamiliaProductos(areaCentral.getCantFramProd());	
		}
		if(sistema!=null){
			motor.setFlujoPagoProveedores(sistema.getFlujoPagoProvee());
			motor.setFlujoPagoHaberes(sistema.getFlujoPagoHaberes());
		}
		if(finanza!=null){
			motor.setMargenTotal(finanza.getMargenTotal());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
		}
		
		if(segmento!=null){
			motor.setSegmentoCliente(segmento.getNombre());
		}
	
		
		//motor.setValorCliente(cliente.getValorCliente());
		System.out.println(" cliente.getValorCliente() " +motor.getValorCliente());
		
		return motor;
		
	}
	public Motor hallarMotorParticular(Motor motor,Cliente cliente,
			AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, String ruc, 
			BigDecimal ingreso, TipoBanca tipoBanca,RuleBase ruleBase, BigDecimal peso){
		
		motor.setTipoBanca(tipoBanca);
		if(finanza!=null){
			motor.setMargenOrdinario(finanza.getMargenOrd());
			motor.setSaldoMedioActivo(finanza.getSaldoMedioAct());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
			motor.setSpreadConsumo(finanza.getSpreadCon());
			motor.setSpreadHipotecario(finanza.getSpreadHipo());
		}
		if(sistema!=null){
			if(sistema.getEsPagoHabiente().equalsIgnoreCase("S")){
				motor.setEsPagoHabiente(true);
			}else{
				motor.setEsPagoHabiente(false);
			}
		}
		if(areaCentral!=null){
			motor.setCuotaRiesgo(areaCentral.getCuotaRiesgoTotal());
			motor.setDeudaHipotecaria(areaCentral.getDeudaHipoBbva().add(areaCentral.getDeudaHipoOtros()));
			motor.setDeudaConsumo(areaCentral.getDeudaConsBbva().add(areaCentral.getDeudaConsOtros()));
			motor.setHipotecario(areaCentral.getDeudaHipoBbva());
			motor.setConsumo(areaCentral.getDeudaConsBbva());
			motor.setTarjetaCredito(areaCentral.getDeudaTarjBbva());
		}
		if(medioPago!=null){
			motor.setLineaMaximaTarjetaCredito(medioPago.getLineaMaxTcBbva());
			motor.setSpreadTarjetaCredito(medioPago.getSpreadTc());
		}
		if(cliente!=null){
			motor.setUbigeoDireccionCliente(cliente.getUbigeoCliente());
		}
		
		motor.setIngreso(ingreso);
		motor.setPeso(peso);	
		EmpresaTop empresaTop=empresaTopDAO.obtenerEmpresaTopxRuc(ruc);
		if(empresaTop==null){
			motor.setEsRepresentanteTop(false);
		}else{
			motor.setEsRepresentanteTop(true);
		}
				
		return motor;
	}
	
	
	@Override
	public Motor calcularVinculacionCliente(Sistema sistema,AreaCentral areaCentral, RiesgoMotor riesgoMotor, Segmento segmento,Finanza finanza,RuleBase ruleBase){
		Motor motor=new Motor();
		motor.setTipoBanca(new TipoBanca());	
		if(areaCentral!=null){
			motor.setCantidadFamiliaProductos(areaCentral.getCantFramProd());
		}
		if(riesgoMotor!=null){
			motor.setVentasTotales(riesgoMotor.getVentasTotales());
		}
		if(sistema!=null){
			motor.setFlujoPagoProveedores(sistema.getFlujoPagoProvee());
			motor.setFlujoPagoHaberes(sistema.getFlujoPagoHaberes());
		}
		if(finanza!=null){
			motor.setMargenTotal(finanza.getMargenTotal());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
		}
		if(segmento!=null){
			motor.setSegmentoCliente(segmento.getNombre());
		}
		correrReglas(ruleBase, motor, "Flujo Pago Proveedores");
		correrReglas(ruleBase, motor, "Margen Total");
		correrReglas(ruleBase, motor, "Flujo Pago Haberes");
		correrReglas(ruleBase, motor, "Saldo Medio Pasivo");
		correrReglas(ruleBase,motor,"Valor Cliente BEC");
		return motor;
	}
	
	@Override
	public Motor calcularTeaBEC(Cliente cliente, Operacion operacion, AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, TipoBanca tipoBanca, Segmento segmento,RuleBase ruleBase) {
		
		List<Valor> divisaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.DIVISA_CARGA);
		List<Valor> grupoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.GRUPO_PROD_CARGA_RAR);
		List<Valor> montoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_BEC_RAR);
		List<Valor> scoreVinculadoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.SCORE_VINCULADO);
		Valor tipoCarga=valorDAO.obtenerValorxCodigo(Valor.CODIGO.BEC_CARGA);
		Valor estadoActivo=valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		Motor motor=new Motor();
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if(riesgoMotor!=null){
			motor.setVentasTotales(riesgoMotor.getVentasTotales());
			if(StringUtils.isNotBlank(riesgoMotor.getEscalaRating())){
				motor.setEscalaRating(riesgoMotor.getEscalaRating());	
			}else{
				motor.setEscalaRating(Constante.NB_ESCALARATING);
			}
					
		}else{
			motor.setEscalaRating(Constante.NB_ESCALARATING);
		}
		if(areaCentral!=null){
			motor.setCantidadFamiliaProductos(areaCentral.getCantFramProd());	
		}
		if(sistema!=null){
			motor.setFlujoPagoProveedores(sistema.getFlujoPagoProvee());
			motor.setFlujoPagoHaberes(sistema.getFlujoPagoHaberes());
		}
		if(finanza!=null){
			motor.setMargenTotal(finanza.getMargenTotal());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
		}
		
		if(segmento!=null){
			motor.setSegmentoCliente(segmento.getNombre());
		}
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		BigDecimal plazoDias=operacion.getPlazo().multiply(new BigDecimal(operacion.getTipoPlazo().getDescripcion()));
		
		obtenerMoneda(motor, operacion, divisaCargas);
		obtenerGrupo(motor, operacion, grupoCargas);
		obtenerMonto(motor, operacion, montoCargas);
		motor.setVentasTotales(motor.getVentasTotales()==null?new BigDecimal(0):motor.getVentasTotales());
		motor.setValorCliente(cliente.getValorCliente());
		motor.setSegmentoCliente(motor.getSegmentoCliente()==null?"":motor.getSegmentoCliente());
		correrReglas(ruleBase, motor, "Valor Cliente BEC");
		correrReglas(ruleBase, motor, "Flujo Pago Proveedores");
		correrReglas(ruleBase, motor, "Margen Total");
		correrReglas(ruleBase, motor, "Flujo Pago Haberes");
		correrReglas(ruleBase, motor, "Saldo Medio Pasivo");
		
		obtenerScoreVinculado(motor, scoreVinculadoCargas);
		
		motor.setValorClienteRar(motor.getValorCliente());
		
		Rar rar=new Rar();
		rar.setCodigoMoneda(motor.getMoneda());
		rar.setCodigoGrupoProducto(motor.getGrupo());
		rar.setValorCliente(motor.getValorClienteRar());
		rar.setScoreVinculado(motor.getScoreVinculadoRar());
		rar.setCodigoMonto(motor.getMontoAgrupado());
		rar.setTipoCarga(tipoCarga);
		rar.setEstado(estadoActivo);
		rar=rarDAO.obtenerRar(rar);
		
		if(rar!=null){
			motor.setTasaMinima(rar.getTasaMinima());
			motor.setTasaMaxima(rar.getTasaMaxima());
			motor.setRar(rar.getRarocPropuesto());
			motor.setPuntoOptimo(rar.getPuntoOptimo());
		}
		CrPe crPe=null;
		if(StringUtils.isNotBlank(motor.getEscalaRating())){
			crPe=new CrPe();
			crPe.setEscalaRating(motor.getEscalaRating());
			crPe.setTipoCarga(tipoCarga);
			crPe.setEstado(estadoActivo);
			crPe=crPeDAO.obtenerCrPe(crPe);
		}
		
		if(crPe!=null){
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		}else{
			motor.setCr(BigDecimal.ZERO);
			motor.setPe(BigDecimal.ZERO);
		}
		
		ExcepcionDuracionCf excepcionDuracionCf=new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto().getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf=excepcionDuracionCfDAO.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo=new CostoFondeo();
		if(excepcionDuracionCf!=null){
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf.getAsignarPlazo());
			motor.setPlazoCf(excepcionDuracionCf.getAsignarPlazo());
		}else{
			costoFondeo.setCantidadDiasMaximo(plazoDias);
			motor.setPlazoCf(plazoDias);
		}
		costoFondeo=costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if(costoFondeo!=null){
			motor.setFechaCf(costoFondeo.getFecha());
			if(operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)){
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			}else{
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}
		
		correrReglas(ruleBase, motor, "TEA");
		
		//[10/11/2014 MMM] 01_Requerimiento_Motor_v2.docx
		if(motor.getTasaMinima() != null && motor.getTea().compareTo(motor.getTasaMinima()) == -1) { 
			motor.setTea(motor.getTasaMinima());
		}
		else if(motor.getTasaMaxima() != null && motor.getTea().compareTo(motor.getTasaMaxima()) == 1) { 
			motor.setTea(motor.getTasaMaxima());
		}
		//[10/11/2014 MMM] FIN
		correrReglas(ruleBase, motor, "ERROR");
		
		return motor;
	}
	
	private void obtenerMoneda(Motor motor, Operacion operacion, List<Valor> divisaCargas){
		for (Valor divisa : divisaCargas) {
			if(operacion.getMoneda().getCodigo().equals(divisa.getDescripcion())){
				motor.setMoneda(Long.parseLong(divisa.getCodigo()));
				break;
			}
		}
	}
	
	private void obtenerGrupo(Motor motor, Operacion operacion, List<Valor> grupoCargas){
		for (Valor grupo : grupoCargas) {
			if(StringUtils.isNotBlank(grupo.getDescripcion())){
				for (String codigo : StringUtils.split(grupo.getDescripcion(),",")) {
					if(operacion.getProducto().getCodigo().equals(codigo)){
						motor.setGrupo(Long.parseLong(grupo.getCodigo()));
						break;
					}
				}
				if(motor.getGrupo()!=null){
					break;
				}
			}
		}
	}
	
	private void obtenerMonto(Motor motor, Operacion operacion, List<Valor> montoCargas){
		for (Valor monto : montoCargas) {
			if(motor.getMoneda()==Long.parseLong(monto.getNombre()) && 
					(ModpreUtil.esMayor(operacion.getMontoCredito(), monto.getAux1()) ||
					ModpreUtil.esIgual(operacion.getMontoCredito(), monto.getAux1())) &&
					(ModpreUtil.esMenor(operacion.getMontoCredito(), monto.getAux2()) ||
					ModpreUtil.esIgual(operacion.getMontoCredito(), monto.getAux2()))){
				motor.setMontoAgrupado(Long.parseLong(monto.getCodigo()));
				break;
			}
		}
	}
	
	private void obtenerScoreVinculado(Motor motor, List<Valor> scoreVinculadoCargas){
		for (Valor score : scoreVinculadoCargas) {
			if((ModpreUtil.esMayor(motor.getScoreVinculado(), score.getAux1()) ||
					ModpreUtil.esIgual(motor.getScoreVinculado(), score.getAux1())) &&
					(ModpreUtil.esMenor(motor.getScoreVinculado(), score.getAux2()) ||
					ModpreUtil.esIgual(motor.getScoreVinculado(), score.getAux2()))){
				motor.setScoreVinculadoRar(new BigDecimal(score.getCodigo()));
				break;
			}
		}
	}
	
	@Override
	public Motor calcularTeaRarBEC(Cliente cliente, Operacion operacion,
			AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, TipoBanca tipoBanca, Segmento segmento, BigDecimal rar,RuleBase ruleBase) {
		Valor tipoCarga=valorDAO.obtenerValorxCodigo(Valor.CODIGO.BEC_CARGA);
		Valor estadoActivo=valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		
		Motor motor=new Motor();
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if(riesgoMotor!=null){
			motor.setVentasTotales(riesgoMotor.getVentasTotales());
			motor.setEscalaRating(riesgoMotor.getEscalaRating());		
		}
		if(areaCentral!=null){
			motor.setCantidadFamiliaProductos(areaCentral.getCantFramProd());	
		}
		if(sistema!=null){
			motor.setFlujoPagoProveedores(sistema.getFlujoPagoProvee());
			motor.setFlujoPagoHaberes(sistema.getFlujoPagoHaberes());
		}
		if(finanza!=null){
			motor.setMargenTotal(finanza.getMargenTotal());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
		}
		
		if(segmento!=null){
			motor.setSegmentoCliente(segmento.getNombre());
		}
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		BigDecimal plazoDias=operacion.getPlazo().multiply(new BigDecimal(operacion.getTipoPlazo().getDescripcion()));
		
		/*obtenerMoneda(motor, operacion, divisaCargas);
		obtenerGrupo(motor, operacion, grupoCargas);
		obtenerMonto(motor, operacion, montoCargas);*/
		
		motor.setValorCliente(cliente.getValorCliente());
		
		motor.setRar(rar);
		
		CrPe crPe=new CrPe();
		crPe.setEscalaRating(motor.getEscalaRating());
		crPe.setTipoCarga(tipoCarga);
		crPe.setEstado(estadoActivo);
		crPe=crPeDAO.obtenerCrPe(crPe);
		
		if(crPe!=null){
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		}
		
		ExcepcionDuracionCf excepcionDuracionCf=new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto().getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf=excepcionDuracionCfDAO.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo=new CostoFondeo();
		if(excepcionDuracionCf!=null){
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf.getAsignarPlazo());
		}else{
			costoFondeo.setCantidadDiasMaximo(plazoDias);
		}
		costoFondeo=costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if(costoFondeo!=null){
			if(operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)){
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			}else{
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}
		motor.setVentasTotales(motor.getVentasTotales()==null?new BigDecimal(0):motor.getVentasTotales());
		motor.setValorCliente(cliente.getValorCliente());
		motor.setSegmentoCliente(motor.getSegmentoCliente()==null?"":motor.getSegmentoCliente());
		correrReglas(ruleBase, motor, "TEA");
		
		return motor;
	}

	@Override
	public Motor calcularRarTeaBEC(Cliente cliente, Operacion operacion,
			AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, TipoBanca tipoBanca, Segmento segmento, BigDecimal tea,RuleBase ruleBase) {
		Valor tipoCarga=valorDAO.obtenerValorxCodigo(Valor.CODIGO.BEC_CARGA);
		Valor estadoActivo=valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		
		Motor motor=new Motor();
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if(riesgoMotor!=null){
			motor.setVentasTotales(riesgoMotor.getVentasTotales());
			motor.setEscalaRating(riesgoMotor.getEscalaRating());		
		}
		if(areaCentral!=null){
			motor.setCantidadFamiliaProductos(areaCentral.getCantFramProd());	
		}
		if(sistema!=null){
			motor.setFlujoPagoProveedores(sistema.getFlujoPagoProvee());
			motor.setFlujoPagoHaberes(sistema.getFlujoPagoHaberes());
		}
		if(finanza!=null){
			motor.setMargenTotal(finanza.getMargenTotal());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
		}
		
		if(segmento!=null){
			motor.setSegmentoCliente(segmento.getNombre());
		}
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		BigDecimal plazoDias=operacion.getPlazo().multiply(new BigDecimal(operacion.getTipoPlazo().getDescripcion()));
		
		/*obtenerMoneda(motor, operacion, divisaCargas);
		obtenerGrupo(motor, operacion, grupoCargas);
		obtenerMonto(motor, operacion, montoCargas);*/
		
		motor.setTea(tea);
		
		CrPe crPe=new CrPe();
		crPe.setEscalaRating(motor.getEscalaRating());
		crPe.setTipoCarga(tipoCarga);
		crPe.setEstado(estadoActivo);
		crPe=crPeDAO.obtenerCrPe(crPe);
		
		if(crPe!=null){
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		}
		
		ExcepcionDuracionCf excepcionDuracionCf=new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto().getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf=excepcionDuracionCfDAO.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo=new CostoFondeo();
		if(excepcionDuracionCf!=null){
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf.getAsignarPlazo());
		}else{
			costoFondeo.setCantidadDiasMaximo(plazoDias);
		}
		costoFondeo=costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if(costoFondeo!=null){
			if(operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)){
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			}else{
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}
		
		correrReglas(ruleBase, motor, "RAR");
		
		return motor;
	}

	@Override
	public Motor calcularTeaHipotecario(Cliente cliente, Operacion operacion,
			AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, String ruc, BigDecimal ingreso, TipoBanca tipoBanca,RuleBase ruleBase) {
		List<Valor> divisaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.DIVISA_CARGA);
		List<Valor> montoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_HIPO_RAR);
		List<Valor> productoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PROD_CARGA_HIPOT);
		List<Valor> plazoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.PLAZO_CARGA);
		List<Valor> viviendaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_VIV_DIVISA_CARGA);
		List<Valor> puntajeBuroCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PUNTAJE_BURO_HIP);
		List<Valor> antiguedadCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_ANTIGUEDAD_CARGA);
		List<Valor> ltvCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_LTV_CARGA);
		List<Valor> valorClienteCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.VAL_CLIENTE_RAR_MIN);
		Valor tipoCarga=valorDAO.obtenerValorxCodigo(Valor.CODIGO.HIPOTECARIO_CARGA);
		Valor estadoActivo=valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		
		Motor motor=new Motor();
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if(finanza!=null){
			motor.setMargenOrdinario(finanza.getMargenOrd());
			motor.setSaldoMedioActivo(finanza.getSaldoMedioAct());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
			motor.setSpreadConsumo(finanza.getSpreadCon());
			motor.setSpreadHipotecario(finanza.getSpreadHipo());
		}
		if(sistema!=null){
			if(sistema.getEsPagoHabiente().equalsIgnoreCase("S")){
				motor.setEsPagoHabiente(true);
			}else{
				motor.setEsPagoHabiente(false);
			}
		}
		if(areaCentral!=null){
			motor.setCuotaRiesgo(areaCentral.getCuotaRiesgoTotal());
			motor.setDeudaHipotecaria(areaCentral.getDeudaHipoBbva().add(areaCentral.getDeudaHipoOtros()));
			motor.setDeudaConsumo(areaCentral.getDeudaConsBbva().add(areaCentral.getDeudaConsOtros()));
			motor.setHipotecario(areaCentral.getDeudaHipoBbva());
			motor.setConsumo(areaCentral.getDeudaConsBbva());
			motor.setTarjetaCredito(areaCentral.getDeudaTarjBbva());
		}
		if(medioPago!=null){
			motor.setLineaMaximaTarjetaCredito(medioPago.getLineaMaxTcBbva());
			motor.setSpreadTarjetaCredito(medioPago.getSpreadTc());
		}
		if(cliente!=null){
			motor.setUbigeoDireccionCliente(cliente.getUbigeoCliente());
		}
		
		motor.setIngreso(ingreso);
			
		EmpresaTop empresaTop=empresaTopDAO.obtenerEmpresaTopxRuc(ruc);
		if(empresaTop==null){
			motor.setEsRepresentanteTop(false);
		}else{
			motor.setEsRepresentanteTop(true);
		}
		motor.setPeso(operacion.getProducto().getPeso());
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		
		obtenerMoneda(motor, operacion, divisaCargas);
		
		obtenerGrupo(motor, operacion, productoCargas);
		
		obtenerMontoHipotecario(motor, operacion, montoCargas);
		
		BigDecimal plazoDias=operacion.getPlazo().multiply(new BigDecimal(operacion.getTipoPlazo().getDescripcion()));
		
		obtenerPlazo(motor, plazoDias, plazoCargas);
		
		obtenerPuntajeBuro(motor, riesgoMotor, puntajeBuroCargas);
		
		obtenerAntiguedad(motor, cliente, antiguedadCargas);
		
		obtenerCodigoVivienda(motor, operacion, viviendaCargas);
		
		obtenerCodigoLtv(motor, operacion, ltvCargas);
		
		motor.setVentasTotales(motor.getVentasTotales()==null?new BigDecimal(0):motor.getVentasTotales());
		motor.setValorCliente(cliente.getValorCliente());
		motor.setSegmentoCliente(motor.getSegmentoCliente()==null?"":motor.getSegmentoCliente());
		
		correrReglas(ruleBase, motor, "Margen Mix");
		correrReglas(ruleBase, motor, "Valor Comercial Actual Hipotecario");
		correrReglas(ruleBase, motor, "Valor Comercial Potencial Hipotecario");
		correrReglas(ruleBase, motor, "Valor Cliente Hipotecario");
		
		obtenerValorCliente(motor, valorClienteCargas);
		
		Rar rar=new Rar();
		rar.setCodigoGrupoProducto(motor.getGrupo());
		rar.setCodigoMoneda(motor.getMoneda());
		rar.setCodigoMonto(motor.getMontoAgrupado());
		rar.setCodigoPlazo(motor.getPlazo().longValueExact());
		rar.setValorCliente(motor.getValorClienteRar());
		rar.setTipoCarga(tipoCarga);
		rar.setEstado(estadoActivo);
		rar=rarDAO.obtenerRar(rar);
		
		if(rar!=null){		
			motor.setTasaMinima(rar.getTasaMinima());
			motor.setTasaMaxima(rar.getTasaMaxima());
			motor.setRar(rar.getRar());
			motor.setPuntoOptimo(rar.getPuntoOptimo());
		}
		
		CrPe crPe=null;
		if(motor.getPuntajeBuro()!=null && motor.getAntiguedadCliente()!=null){
			crPe=new CrPe();
			crPe.setCodigoProducto(motor.getGrupo());
			crPe.setCodigoPuntajeBuro(motor.getPuntajeBuro().longValueExact());
			crPe.setCodigoAntiguedadCliente(motor.getAntiguedadCliente().longValueExact());
			crPe.setCodigoDivisa(motor.getMoneda());
			crPe.setCodigoViviendaDivisa(motor.getCodigoViviendaDivisa());
			crPe.setCodigoLtv(motor.getCodigoLtv());
			crPe.setTipoCarga(tipoCarga);
			crPe.setEstado(estadoActivo);
			crPe=crPeDAO.obtenerCrPe(crPe);
		}
		
		if(crPe!=null){
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		}else{
			motor.setCr(BigDecimal.ZERO);
			motor.setPe(BigDecimal.ZERO);
		}
		
		ExcepcionDuracionCf excepcionDuracionCf=new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto().getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf=excepcionDuracionCfDAO.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo=new CostoFondeo();
		if(excepcionDuracionCf!=null){
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf.getAsignarPlazo());
			motor.setPlazoCf(excepcionDuracionCf.getAsignarPlazo());
		}else{
			costoFondeo.setCantidadDiasMaximo(plazoDias);
			motor.setPlazoCf(plazoDias);
		}
		costoFondeo=costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if(costoFondeo!=null){
			motor.setFechaCf(costoFondeo.getFecha());
			if(operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)){
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			}else{
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}
		
		correrReglas(ruleBase, motor, "TEA");
		
		//[10/11/2014 MMM] 01_Requerimiento_Motor_v2.docx
		if (motor.getTasaMinima() != null
				&& motor.getTea().compareTo(motor.getTasaMinima()) == -1) {
			motor.setTea(motor.getTasaMinima());
		} else if (motor.getTasaMaxima() != null
				&& motor.getTea().compareTo(motor.getTasaMaxima()) == 1) {
			motor.setTea(motor.getTasaMaxima());
		}
		// [10/11/2014 MMM] FIN
		correrReglas(ruleBase, motor, "ERROR");
		
		return motor;
	}

	private void obtenerMontoConsumo(Motor motor, Operacion operacion, List<Valor> montoCargas){
		for (Valor monto : montoCargas) {
			if(motor.getMoneda()==monto.getAux1().longValueExact() && 
					motor.getGrupo().longValue()==monto.getAux4().longValueExact() &&
					(ModpreUtil.esMayor(operacion.getMontoCredito(), monto.getAux2()) ||
					ModpreUtil.esIgual(operacion.getMontoCredito(), monto.getAux2())) &&
					(ModpreUtil.esMenor(operacion.getMontoCredito(), monto.getAux3()) ||
					ModpreUtil.esIgual(operacion.getMontoCredito(), monto.getAux3()))){
				motor.setMontoAgrupado(Long.parseLong(monto.getCodigo()));
				break;
			}
		}
	}
	
	private void obtenerPlazoCrPE(Motor motor ,BigDecimal plazoDias,List<Valor> plazoCrPes){
		for (Valor plazo : plazoCrPes) {
			if(motor.getGrupo().longValue()==plazo.getAux1().longValueExact() &&
					(ModpreUtil.esMayor(plazoDias, plazo.getAux2()) ||
					ModpreUtil.esIgual(plazoDias, plazo.getAux2())) &&
					(ModpreUtil.esMenor(plazoDias, plazo.getAux3()) ||
					ModpreUtil.esIgual(plazoDias, plazo.getAux3()))){
				motor.setPlazoCrPe(new BigDecimal(plazo.getCodigo()));
				break;
			}
		}
	}
	public void obtenerMontoHipotecario(Motor motor, Operacion operacion, List<Valor> montoCargas){
		for (Valor monto : montoCargas) {
			if(motor.getMoneda()==monto.getAux1().longValueExact() && 
					(ModpreUtil.esMayor(operacion.getMontoCredito(), monto.getAux2()) ||
					ModpreUtil.esIgual(operacion.getMontoCredito(), monto.getAux2())) &&
					(ModpreUtil.esMenor(operacion.getMontoCredito(), monto.getAux3()) ||
					ModpreUtil.esIgual(operacion.getMontoCredito(), monto.getAux3()))){
				motor.setMontoAgrupado(Long.parseLong(monto.getCodigo()));
				break;
			}
		}
	}
	
	private void obtenerPlazo(Motor motor, BigDecimal plazoDias, List<Valor> plazoCargas){
		for (Valor plazo : plazoCargas) {
			if(motor.getMoneda()==plazo.getAux3().longValueExact() && 
					(ModpreUtil.esMayor(plazoDias, plazo.getAux1()) ||
					ModpreUtil.esIgual(plazoDias, plazo.getAux1())) &&
					(ModpreUtil.esMenor(plazoDias, plazo.getAux2()) ||
					ModpreUtil.esIgual(plazoDias, plazo.getAux2()))){
				motor.setPlazo(new BigDecimal(plazo.getCodigo()));
				break;
			}
		}
	}
	
	private void obtenerPuntajeBuro(Motor motor, RiesgoMotor riesgoMotor, List<Valor> puntajeBuroCargas){
		BigDecimal puntajeBuro=BigDecimal.ZERO;
		if(riesgoMotor!=null && riesgoMotor.getPuntajeBuro()!=null){
			puntajeBuro=riesgoMotor.getPuntajeBuro();
		}
		for (Valor puntaje : puntajeBuroCargas) {
			if((ModpreUtil.esMayor(puntajeBuro, puntaje.getAux1()) ||
					ModpreUtil.esIgual(puntajeBuro, puntaje.getAux1())) &&
					(ModpreUtil.esMenor(puntajeBuro, puntaje.getAux2()) ||
					ModpreUtil.esIgual(puntajeBuro, puntaje.getAux2()))){
				motor.setPuntajeBuro(new BigDecimal(puntaje.getCodigo()));
				break;
			}
		}
	}
		
	private void obtenerAntiguedad(Motor motor, Cliente cliente, List<Valor> antiguedadCargas){
		BigDecimal antiguedadNumero=BigDecimal.ZERO;
		if(StringUtils.isNotBlank(cliente.getAntiguedadCliente())){
			antiguedadNumero=new BigDecimal(cliente.getAntiguedadCliente());
		}
		for (Valor antiguedad : antiguedadCargas) {
			if((ModpreUtil.esMayor(antiguedadNumero, antiguedad.getAux1()) ||
					ModpreUtil.esIgual(antiguedadNumero, antiguedad.getAux1())) &&
					(ModpreUtil.esMenor(antiguedadNumero, antiguedad.getAux2()) ||
					ModpreUtil.esIgual(antiguedadNumero, antiguedad.getAux2()))){
				motor.setAntiguedadCliente(new BigDecimal(antiguedad.getCodigo()));
				break;
			}
		}
	}
	
	public void obtenerValorCliente(Motor motor, List<Valor> valorClienteCargas){
		for (Valor valor : valorClienteCargas) {
			if((ModpreUtil.esMayor(motor.getValorCliente(), valor.getAux1()) ||
					ModpreUtil.esIgual(motor.getValorCliente(), valor.getAux1())) &&
					(ModpreUtil.esMenor(motor.getValorCliente(), valor.getAux2()) ||
					ModpreUtil.esIgual(motor.getValorCliente(), valor.getAux2()))){
				motor.setValorClienteRar(new BigDecimal(valor.getCodigo()));
				break;
			}
		}
	}
	
	private void obtenerCodigoVivienda(Motor motor, Operacion operacion, List<Valor> viviendaCargas){
		BigDecimal codigoVivienda;
		if(operacion.getPropiedad()){
			codigoVivienda=new BigDecimal("1");
		}else{
			codigoVivienda=new BigDecimal("2");
		}
		for (Valor vivienda : viviendaCargas) {
			if(ModpreUtil.esIgual(codigoVivienda, vivienda.getAux1()) && 
					ModpreUtil.esIgual(new BigDecimal(motor.getMoneda()), vivienda.getAux2())){
				motor.setCodigoViviendaDivisa(Long.parseLong(vivienda.getCodigo()));
				break;
			}
		}
	}
	
	private void obtenerCodigoLtv(Motor motor, Operacion operacion, List<Valor> ltvCargas){
		BigDecimal ltvMonto=operacion.getMontoCredito().divide(operacion.getPrecioBien(),2,BigDecimal.ROUND_CEILING);
		for (Valor ltv : ltvCargas) {
			if(motor.getCodigoViviendaDivisa()!=null && motor.getCodigoViviendaDivisa()==ltv.getAux1().longValueExact() && 
					(ModpreUtil.esMayor(ltvMonto, ltv.getAux2()) ||
					ModpreUtil.esIgual(ltvMonto, ltv.getAux2())) &&
					(ModpreUtil.esMenor(ltvMonto, ltv.getAux3()) ||
					ModpreUtil.esIgual(ltvMonto, ltv.getAux3()))){
				motor.setCodigoLtv(Long.parseLong(ltv.getCodigo()));
				break;
			}
		}
	}
	
	@Override
	public Motor calcularTeaRarHipotecario(Cliente cliente, 
			Operacion operacion, AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, String ruc, BigDecimal ingreso, 
			TipoBanca tipoBanca, BigDecimal rar,RuleBase ruleBase) {
		List<Valor> divisaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.DIVISA_CARGA);
		List<Valor> montoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_HIPO_RAR);
		List<Valor> productoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PROD_CARGA_HIPOT);
		List<Valor> plazoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.PLAZO_CARGA);
		List<Valor> viviendaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_VIV_DIVISA_CARGA);
		List<Valor> puntajeBuroCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PUNTAJE_BURO_HIP);
		List<Valor> antiguedadCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_ANTIGUEDAD_CARGA);
		List<Valor> ltvCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_LTV_CARGA);
		Valor tipoCarga=valorDAO.obtenerValorxCodigo(Valor.CODIGO.HIPOTECARIO_CARGA);
		Valor estadoActivo=valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		
		Motor motor=new Motor();
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if(finanza!=null){
			motor.setMargenOrdinario(finanza.getMargenOrd());
			motor.setSaldoMedioActivo(finanza.getSaldoMedioAct());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
			motor.setSpreadConsumo(finanza.getSpreadCon());
			motor.setSpreadHipotecario(finanza.getSpreadHipo());
		}
		if(sistema!=null){
			if(sistema.getEsPagoHabiente().equalsIgnoreCase("S")){
				motor.setEsPagoHabiente(true);
			}else{
				motor.setEsPagoHabiente(false);
			}
		}
		if(areaCentral!=null){
			motor.setCuotaRiesgo(areaCentral.getCuotaRiesgoTotal());
			motor.setDeudaHipotecaria(areaCentral.getDeudaHipoBbva().add(areaCentral.getDeudaHipoOtros()));
			motor.setDeudaConsumo(areaCentral.getDeudaConsBbva().add(areaCentral.getDeudaConsOtros()));
			motor.setHipotecario(areaCentral.getDeudaHipoBbva());
			motor.setConsumo(areaCentral.getDeudaConsBbva());
			motor.setTarjetaCredito(areaCentral.getDeudaTarjBbva());
		}
		if(medioPago!=null){
			motor.setLineaMaximaTarjetaCredito(medioPago.getLineaMaxTcBbva());
			motor.setSpreadTarjetaCredito(medioPago.getSpreadTc());
		}
		if(cliente!=null){
			motor.setUbigeoDireccionCliente(cliente.getUbigeoCliente());
		}
		
		motor.setIngreso(ingreso);
			
		EmpresaTop empresaTop=empresaTopDAO.obtenerEmpresaTopxRuc(ruc);
		if(empresaTop==null){
			motor.setEsRepresentanteTop(false);
		}else{
			motor.setEsRepresentanteTop(true);
		}
		motor.setPeso(operacion.getProducto().getPeso());
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		
		obtenerMoneda(motor, operacion, divisaCargas);
		
		obtenerGrupo(motor, operacion, productoCargas);
		
		obtenerMontoHipotecario(motor, operacion, montoCargas);
		
		BigDecimal plazoDias=operacion.getPlazo().multiply(new BigDecimal(operacion.getTipoPlazo().getDescripcion()));
		obtenerPlazo(motor, plazoDias, plazoCargas);
		
		obtenerPuntajeBuro(motor, riesgoMotor, puntajeBuroCargas);
		
		obtenerAntiguedad(motor, cliente, antiguedadCargas);
		
		obtenerCodigoVivienda(motor, operacion, viviendaCargas);
		
		obtenerCodigoLtv(motor, operacion, ltvCargas);
		
		motor.setRar(rar);
		
		CrPe crPe=new CrPe();
		crPe.setCodigoProducto(motor.getGrupo());
		if(motor.getPuntajeBuro()!=null){
			crPe.setCodigoPuntajeBuro(motor.getPuntajeBuro().longValueExact());
		}
		if(motor.getAntiguedadCliente()!=null){
			crPe.setCodigoAntiguedadCliente(motor.getAntiguedadCliente().longValueExact());
		}
		crPe.setCodigoDivisa(motor.getMoneda());
		crPe.setCodigoViviendaDivisa(motor.getCodigoViviendaDivisa());
		crPe.setCodigoLtv(motor.getCodigoLtv());
		crPe.setTipoCarga(tipoCarga);
		crPe.setEstado(estadoActivo);
		crPe=crPeDAO.obtenerCrPe(crPe);
		
		if(crPe!=null){
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		}
		
		ExcepcionDuracionCf excepcionDuracionCf=new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto().getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf=excepcionDuracionCfDAO.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo=new CostoFondeo();
		if(excepcionDuracionCf!=null){
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf.getAsignarPlazo());
		}else{
			costoFondeo.setCantidadDiasMaximo(plazoDias);
		}
		costoFondeo=costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if(costoFondeo!=null){
			if(operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)){
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			}else{
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}
		motor.setVentasTotales(motor.getVentasTotales()==null?new BigDecimal(0):motor.getVentasTotales());
		motor.setValorCliente(cliente.getValorCliente());
		motor.setSegmentoCliente(motor.getSegmentoCliente()==null?"":motor.getSegmentoCliente());
		correrReglas(ruleBase, motor, "TEA");
		
		return motor;
	}

	@Override
	public Motor calcularRarTeaHipotecario(Cliente cliente, 
			Operacion operacion, AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, String ruc, BigDecimal ingreso, 
			TipoBanca tipoBanca, BigDecimal tea,RuleBase ruleBase) {
		List<Valor> divisaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.DIVISA_CARGA);
		List<Valor> montoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_HIPO_RAR);
		List<Valor> productoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PROD_CARGA_HIPOT);
		List<Valor> plazoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.PLAZO_CARGA);
		List<Valor> viviendaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_VIV_DIVISA_CARGA);
		List<Valor> puntajeBuroCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PUNTAJE_BURO_HIP);
		List<Valor> antiguedadCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_ANTIGUEDAD_CARGA);
		List<Valor> ltvCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_LTV_CARGA);
		Valor tipoCarga=valorDAO.obtenerValorxCodigo(Valor.CODIGO.HIPOTECARIO_CARGA);
		Valor estadoActivo=valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		
		Motor motor=new Motor();
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if(finanza!=null){
			motor.setMargenOrdinario(finanza.getMargenOrd());
			motor.setSaldoMedioActivo(finanza.getSaldoMedioAct());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
			motor.setSpreadConsumo(finanza.getSpreadCon());
			motor.setSpreadHipotecario(finanza.getSpreadHipo());
		}
		if(sistema!=null){
			if(sistema.getEsPagoHabiente().equalsIgnoreCase("S")){
				motor.setEsPagoHabiente(true);
			}else{
				motor.setEsPagoHabiente(false);
			}
		}
		if(areaCentral!=null){
			motor.setCuotaRiesgo(areaCentral.getCuotaRiesgoTotal());
			motor.setDeudaHipotecaria(areaCentral.getDeudaHipoBbva().add(areaCentral.getDeudaHipoOtros()));
			motor.setDeudaConsumo(areaCentral.getDeudaConsBbva().add(areaCentral.getDeudaConsOtros()));
			motor.setHipotecario(areaCentral.getDeudaHipoBbva());
			motor.setConsumo(areaCentral.getDeudaConsBbva());
			motor.setTarjetaCredito(areaCentral.getDeudaTarjBbva());
		}
		if(medioPago!=null){
			motor.setLineaMaximaTarjetaCredito(medioPago.getLineaMaxTcBbva());
			motor.setSpreadTarjetaCredito(medioPago.getSpreadTc());
		}
		if(cliente!=null){
			motor.setUbigeoDireccionCliente(cliente.getUbigeoCliente());
		}
		
		motor.setIngreso(ingreso);
			
		EmpresaTop empresaTop=empresaTopDAO.obtenerEmpresaTopxRuc(ruc);
		if(empresaTop==null){
			motor.setEsRepresentanteTop(false);
		}else{
			motor.setEsRepresentanteTop(true);
		}
		motor.setPeso(operacion.getProducto().getPeso());
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		
		obtenerMoneda(motor, operacion, divisaCargas);
		
		obtenerGrupo(motor, operacion, productoCargas);
		
		obtenerMontoHipotecario(motor, operacion, montoCargas);
		
		BigDecimal plazoDias=operacion.getPlazo().multiply(new BigDecimal(operacion.getTipoPlazo().getDescripcion()));
		obtenerPlazo(motor, plazoDias, plazoCargas);
		
		obtenerPuntajeBuro(motor, riesgoMotor, puntajeBuroCargas);
		
		obtenerAntiguedad(motor, cliente, antiguedadCargas);
		
		obtenerCodigoVivienda(motor, operacion, viviendaCargas);
		
		obtenerCodigoLtv(motor, operacion, ltvCargas);
		
		motor.setTea(tea);
		
		CrPe crPe=new CrPe();
		crPe.setCodigoProducto(motor.getGrupo());
		if(motor.getPuntajeBuro()!=null){
			crPe.setCodigoPuntajeBuro(motor.getPuntajeBuro().longValueExact());
		}
		if(motor.getAntiguedadCliente()!=null){
			crPe.setCodigoAntiguedadCliente(motor.getAntiguedadCliente().longValueExact());
		}
		crPe.setCodigoDivisa(motor.getMoneda());
		crPe.setCodigoViviendaDivisa(motor.getCodigoViviendaDivisa());
		crPe.setCodigoLtv(motor.getCodigoLtv());
		crPe.setTipoCarga(tipoCarga);
		crPe.setEstado(estadoActivo);
		crPe=crPeDAO.obtenerCrPe(crPe);
		
		if(crPe!=null){
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		}
		
		ExcepcionDuracionCf excepcionDuracionCf=new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto().getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf=excepcionDuracionCfDAO.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo=new CostoFondeo();
		if(excepcionDuracionCf!=null){
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf.getAsignarPlazo());
		}else{
			costoFondeo.setCantidadDiasMaximo(plazoDias);
		}
		costoFondeo=costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if(costoFondeo!=null){
			if(operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)){
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			}else{
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}
		
		correrReglas(ruleBase, motor, "RAR");
		
		return motor;
	}

	@Override
	public Motor calcularTeaConsumo(Cliente cliente, Operacion operacion,
			AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, String ruc, BigDecimal ingreso, TipoBanca tipoBanca,RuleBase ruleBase) {
		List<Valor> divisaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.DIVISA_CARGA);
		List<Valor> montoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_CONSU_RAR);
		List<Valor> productoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PROD_CARGA_CONSU);
		List<Valor> puntajeBuroCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PUNTAJE_BURO_CON);
		List<Valor> antiguedadCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_ANTIGUEDAD_CARGA);
		List<Valor> valorClienteCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.VAL_CLIENTE_RAR_MIN);
		List<Valor> plazoCrPes=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PLAZO_CONS_CRPE);
		Valor tipoCarga=valorDAO.obtenerValorxCodigo(Valor.CODIGO.CONSUMO_CARGA);
		Valor estadoActivo=valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		
		Motor motor=new Motor();
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if(finanza!=null){
			motor.setMargenOrdinario(finanza.getMargenOrd());
			motor.setSaldoMedioActivo(finanza.getSaldoMedioAct());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
			motor.setSpreadHipotecario(finanza.getSpreadHipo());
			motor.setSpreadConsumo(finanza.getSpreadCon());
		}
		if(sistema!=null){
			if(sistema.getEsPagoHabiente().equalsIgnoreCase("S")){
				motor.setEsPagoHabiente(true);
			}else{
				motor.setEsPagoHabiente(false);
			}
		}
		if(areaCentral!=null){
			motor.setDeudaHipotecaria(areaCentral.getDeudaHipoBbva().add(areaCentral.getDeudaHipoOtros()));
			motor.setDeudaConsumo(areaCentral.getDeudaConsBbva().add(areaCentral.getDeudaConsOtros()));
			motor.setCuotaRiesgo(areaCentral.getCuotaRiesgoTotal());
			motor.setHipotecario(areaCentral.getDeudaHipoBbva());
			motor.setConsumo(areaCentral.getDeudaConsBbva());
			motor.setTarjetaCredito(areaCentral.getDeudaTarjBbva());
		}
		if(medioPago!=null){
			motor.setLineaMaximaTarjetaCredito(medioPago.getLineaMaxTcBbva());
			motor.setSpreadTarjetaCredito(medioPago.getSpreadTc());
		}
		if(cliente!=null){
			motor.setUbigeoDireccionCliente(cliente.getUbigeoCliente());
		}
		
		motor.setIngreso(ingreso);
		
		EmpresaTop empresaTop=empresaTopDAO.obtenerEmpresaTopxRuc(ruc);
		if(empresaTop==null){
			motor.setEsRepresentanteTop(false);
		}else{
			motor.setEsRepresentanteTop(true);
		}
		motor.setPeso(operacion.getProducto().getPeso());
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		motor.setPlazo(operacion.getPlazo());
		
		BigDecimal plazoDias=operacion.getPlazo().multiply(new BigDecimal(operacion.getTipoPlazo().getDescripcion()));
		
		obtenerMoneda(motor, operacion, divisaCargas);
		
		obtenerGrupo(motor, operacion, productoCargas);
		
		obtenerMontoConsumo(motor, operacion, montoCargas);
		
		obtenerPuntajeBuroConsumo(motor, riesgoMotor, puntajeBuroCargas);
		
		obtenerPlazoCrPE(motor,plazoDias, plazoCrPes);
		
		obtenerAntiguedad(motor, cliente, antiguedadCargas);
		
		correrReglas(ruleBase, motor, "Margen Mix");
		correrReglas(ruleBase, motor, "Valor Comercial Actual Consumo");
		correrReglas(ruleBase, motor, "Valor Comercial Potencial Consumo");
		correrReglas(ruleBase, motor, "Valor Cliente Consumo");
		
		obtenerValorCliente(motor, valorClienteCargas);
		
		Rar rar=new Rar();
		rar.setCodigoGrupoProducto(motor.getGrupo());
		rar.setCodigoMoneda(motor.getMoneda());
		rar.setCodigoMonto(motor.getMontoAgrupado());
		rar.setValorCliente(motor.getValorClienteRar());
		rar.setTipoCarga(tipoCarga);
		rar.setEstado(estadoActivo);
		rar=rarDAO.obtenerRar(rar);
		
		if(rar!=null){		
			motor.setTasaMinima(rar.getTasaMinima());
			motor.setTasaMaxima(rar.getTasaMaxima());
			motor.setRar(rar.getRar());
			motor.setPuntoOptimo(rar.getPuntoOptimo());
		}
		
		CrPe crPe=null;
		if(motor.getPuntajeBuro()!=null && motor.getAntiguedadCliente()!=null){
			crPe=new CrPe();
			crPe.setCodigoProducto(motor.getGrupo());
			crPe.setCodigoPuntajeBuro(motor.getPuntajeBuro().longValueExact());	
			crPe.setCodigoAntiguedadCliente(motor.getAntiguedadCliente().longValueExact());
			crPe.setTipoCarga(tipoCarga);
			crPe.setCodigoPlazo(motor.getPlazoCrPe().longValueExact());
			crPe.setEstado(estadoActivo);
			crPe=crPeDAO.obtenerCrPe(crPe);
		}
		
		if(crPe!=null){
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		}else{
			motor.setCr(BigDecimal.ZERO);
			motor.setPe(BigDecimal.ZERO);
		}
		
		ExcepcionDuracionCf excepcionDuracionCf=new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto().getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf=excepcionDuracionCfDAO.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo=new CostoFondeo();
		if(excepcionDuracionCf!=null){
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf.getAsignarPlazo());
			motor.setPlazoCf(excepcionDuracionCf.getAsignarPlazo());
		}else{
			costoFondeo.setCantidadDiasMaximo(plazoDias);
			motor.setPlazoCf(plazoDias);
		}
		costoFondeo=costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if(costoFondeo!=null){
			motor.setFechaCf(costoFondeo.getFecha());
			if(operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)){
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			}else{
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}
		motor.setVentasTotales(motor.getVentasTotales()==null?new BigDecimal(0):motor.getVentasTotales());
		motor.setValorCliente(cliente.getValorCliente());
		motor.setSegmentoCliente(motor.getSegmentoCliente()==null?"":motor.getSegmentoCliente());
		correrReglas(ruleBase, motor, "TEA");
		
		//[10/11/2014 MMM] 01_Requerimiento_Motor_v2.docx
		if (motor.getTasaMinima() != null
				&& motor.getTea().compareTo(motor.getTasaMinima()) == -1) {
			motor.setTea(motor.getTasaMinima());
		} else if (motor.getTasaMaxima() != null
				&& motor.getTea().compareTo(motor.getTasaMaxima()) == 1) {
			motor.setTea(motor.getTasaMaxima());
		}
		// [10/11/2014 MMM] FIN
		correrReglas(ruleBase, motor, "ERROR");
				
		return motor;
	}

	private void obtenerPuntajeBuroConsumo(Motor motor, RiesgoMotor riesgoMotor, List<Valor> puntajeBuroCargas){
		BigDecimal puntajeBuro=BigDecimal.ZERO;
		if(riesgoMotor!=null && riesgoMotor.getPuntajeBuro()!=null){
			puntajeBuro=riesgoMotor.getPuntajeBuro();
		}
		for (Valor puntaje : puntajeBuroCargas) {
			if(motor.getGrupo()==puntaje.getAux1().longValueExact() &&
					(ModpreUtil.esMayor(puntajeBuro, puntaje.getAux2()) ||
					ModpreUtil.esIgual(puntajeBuro, puntaje.getAux2())) &&
					(ModpreUtil.esMenor(puntajeBuro, puntaje.getAux3()) ||
					ModpreUtil.esIgual(puntajeBuro, puntaje.getAux3()))){
				motor.setPuntajeBuro(new BigDecimal(puntaje.getCodigo()));
				break;
			}
		}
	}
	
	@Override
	public Motor calcularTeaRarConsumo(Cliente cliente, 
			Operacion operacion, AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, String ruc, BigDecimal ingreso, 
			TipoBanca tipoBanca, BigDecimal rar,RuleBase ruleBase) {
		List<Valor> divisaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.DIVISA_CARGA);
		List<Valor> montoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_CONSU_RAR);
		List<Valor> productoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PROD_CARGA_CONSU);
		List<Valor> puntajeBuroCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PUNTAJE_BURO_CON);
		List<Valor> antiguedadCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_ANTIGUEDAD_CARGA);
		Valor tipoCarga=valorDAO.obtenerValorxCodigo(Valor.CODIGO.CONSUMO_CARGA);
		Valor estadoActivo=valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		
		Motor motor=new Motor();
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		if(finanza!=null){
			motor.setMargenOrdinario(finanza.getMargenOrd());
			motor.setSaldoMedioActivo(finanza.getSaldoMedioAct());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
			motor.setSpreadHipotecario(finanza.getSpreadHipo());
			motor.setSpreadConsumo(finanza.getSpreadCon());
		}
		if(sistema!=null){
			if(sistema.getEsPagoHabiente().equalsIgnoreCase("S")){
				motor.setEsPagoHabiente(true);
			}else{
				motor.setEsPagoHabiente(false);
			}
		}
		if(areaCentral!=null){
			motor.setDeudaHipotecaria(areaCentral.getDeudaHipoBbva().add(areaCentral.getDeudaHipoOtros()));
			motor.setDeudaConsumo(areaCentral.getDeudaConsBbva().add(areaCentral.getDeudaConsOtros()));
			motor.setCuotaRiesgo(areaCentral.getCuotaRiesgoTotal());
			motor.setHipotecario(areaCentral.getDeudaHipoBbva());
			motor.setConsumo(areaCentral.getDeudaConsBbva());
			motor.setTarjetaCredito(areaCentral.getDeudaTarjBbva());
		}
		if(medioPago!=null){
			motor.setLineaMaximaTarjetaCredito(medioPago.getLineaMaxTcBbva());
			motor.setSpreadTarjetaCredito(medioPago.getSpreadTc());
		}
		if(cliente!=null){
			motor.setUbigeoDireccionCliente(cliente.getUbigeoCliente());
		}
		
		motor.setIngreso(ingreso);
		
		EmpresaTop empresaTop=empresaTopDAO.obtenerEmpresaTopxRuc(ruc);
		if(empresaTop==null){
			motor.setEsRepresentanteTop(false);
		}else{
			motor.setEsRepresentanteTop(true);
		}
		motor.setPeso(operacion.getProducto().getPeso());
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		motor.setPlazo(operacion.getPlazo());
		
		BigDecimal plazoDias=operacion.getPlazo().multiply(new BigDecimal(operacion.getTipoPlazo().getDescripcion()));
		
		obtenerMoneda(motor, operacion, divisaCargas);
		
		obtenerGrupo(motor, operacion, productoCargas);
		
		obtenerMontoConsumo(motor, operacion, montoCargas);
		
		obtenerPuntajeBuroConsumo(motor, riesgoMotor, puntajeBuroCargas);
		
		obtenerAntiguedad(motor, cliente, antiguedadCargas);
		
		motor.setRar(rar);
		
		
		CrPe crPe=new CrPe();
		crPe.setCodigoProducto(motor.getGrupo());
		if(motor.getPuntajeBuro()!=null){
			crPe.setCodigoPuntajeBuro(motor.getPuntajeBuro().longValueExact());	
		}
		if(motor.getAntiguedadCliente()!=null){
			crPe.setCodigoAntiguedadCliente(motor.getAntiguedadCliente().longValueExact());
		}
		crPe.setTipoCarga(tipoCarga);
		crPe.setEstado(estadoActivo);
		crPe=crPeDAO.obtenerCrPe(crPe);
		
		if(crPe!=null){
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		}
		
		ExcepcionDuracionCf excepcionDuracionCf=new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto().getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf=excepcionDuracionCfDAO.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo=new CostoFondeo();
		if(excepcionDuracionCf!=null){
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf.getAsignarPlazo());
		}else{
			costoFondeo.setCantidadDiasMaximo(plazoDias);
		}
		costoFondeo=costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if(costoFondeo!=null){
			if(operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)){
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			}else{
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}
		motor.setVentasTotales(motor.getVentasTotales()==null?new BigDecimal(0):motor.getVentasTotales());
		motor.setValorCliente(cliente.getValorCliente());
		motor.setSegmentoCliente(motor.getSegmentoCliente()==null?"":motor.getSegmentoCliente());
		correrReglas(ruleBase, motor, "TEA");
		
		return motor;
	}


	@Override
	public Motor calcularRarTeaConsumo(Cliente cliente, 
			Operacion operacion, AreaCentral areaCentral, Finanza finanza, MedioPago medioPago,
			RiesgoMotor riesgoMotor, Sistema sistema, String ruc, BigDecimal ingreso, 
			TipoBanca tipoBanca, BigDecimal tea,RuleBase ruleBase) {
		List<Valor> divisaCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.DIVISA_CARGA);
		List<Valor> montoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.MONTO_CARGA_CONSU_RAR);
		List<Valor> productoCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PROD_CARGA_CONSU);
		List<Valor> puntajeBuroCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_PUNTAJE_BURO_CON);
		List<Valor> antiguedadCargas=valorDAO.obtenerValoresxLista(Lista.CODIGO.COD_ANTIGUEDAD_CARGA);
		Valor tipoCarga=valorDAO.obtenerValorxCodigo(Valor.CODIGO.CONSUMO_CARGA);
		Valor estadoActivo=valorDAO.obtenerValorxCodigo(Valor.CODIGO.ACTIVO);
		
		Motor motor=new Motor();
		agregarDatosComunes(motor, operacion, cliente);
		motor.setTipoBanca(tipoBanca);
		
		if(finanza!=null){
			motor.setMargenOrdinario(finanza.getMargenOrd());
			motor.setSaldoMedioActivo(finanza.getSaldoMedioAct());
			motor.setSaldoMedioPasivo(finanza.getSaldoMedioPas());
			motor.setSpreadHipotecario(finanza.getSpreadHipo());
			motor.setSpreadConsumo(finanza.getSpreadCon());
		}
		if(sistema!=null){
			if(sistema.getEsPagoHabiente().equalsIgnoreCase("S")){
				motor.setEsPagoHabiente(true);
			}else{
				motor.setEsPagoHabiente(false);
			}
		}
		if(areaCentral!=null){
			motor.setDeudaHipotecaria(areaCentral.getDeudaHipoBbva().add(areaCentral.getDeudaHipoOtros()));
			motor.setDeudaConsumo(areaCentral.getDeudaConsBbva().add(areaCentral.getDeudaConsOtros()));
			motor.setCuotaRiesgo(areaCentral.getCuotaRiesgoTotal());
			motor.setHipotecario(areaCentral.getDeudaHipoBbva());
			motor.setConsumo(areaCentral.getDeudaConsBbva());
			motor.setTarjetaCredito(areaCentral.getDeudaTarjBbva());
		}
		if(medioPago!=null){
			motor.setLineaMaximaTarjetaCredito(medioPago.getLineaMaxTcBbva());
			motor.setSpreadTarjetaCredito(medioPago.getSpreadTc());
		}
		if(cliente!=null){
			motor.setUbigeoDireccionCliente(cliente.getUbigeoCliente());
		}
		
		motor.setIngreso(ingreso);
		
		EmpresaTop empresaTop=empresaTopDAO.obtenerEmpresaTopxRuc(ruc);
		if(empresaTop==null){
			motor.setEsRepresentanteTop(false);
		}else{
			motor.setEsRepresentanteTop(true);
		}
		motor.setPeso(operacion.getProducto().getPeso());
		motor.setCadic(operacion.getProducto().getCadic());
		motor.setComisiones(operacion.getProducto().getComision());
		motor.setTipoImpositivo(operacion.getProducto().getTipoImpositivo());
		motor.setRatioEficiencia(operacion.getProducto().getRatioEficiencia());
		motor.setPlazo(operacion.getPlazo());
		
		BigDecimal plazoDias=operacion.getPlazo().multiply(new BigDecimal(operacion.getTipoPlazo().getDescripcion()));
		
		obtenerMoneda(motor, operacion, divisaCargas);
		
		obtenerGrupo(motor, operacion, productoCargas);
		
		obtenerMontoConsumo(motor, operacion, montoCargas);
		
		obtenerPuntajeBuroConsumo(motor, riesgoMotor, puntajeBuroCargas);
		
		obtenerAntiguedad(motor, cliente, antiguedadCargas);
		
		motor.setTea(tea);
		
		
		CrPe crPe=new CrPe();
		crPe.setCodigoProducto(motor.getGrupo());
		if(motor.getPuntajeBuro()!=null){
			crPe.setCodigoPuntajeBuro(motor.getPuntajeBuro().longValueExact());	
		}
		if(motor.getAntiguedadCliente()!=null){
			crPe.setCodigoAntiguedadCliente(motor.getAntiguedadCliente().longValueExact());
		}
		crPe.setTipoCarga(tipoCarga);
		crPe.setEstado(estadoActivo);
		crPe=crPeDAO.obtenerCrPe(crPe);
		
		if(crPe!=null){
			motor.setCr(crPe.getCr());
			motor.setPe(crPe.getPe());
		}
		
		ExcepcionDuracionCf excepcionDuracionCf=new ExcepcionDuracionCf();
		excepcionDuracionCf.setCodigoProducto(operacion.getProducto().getCodigo());
		excepcionDuracionCf.setMoneda(operacion.getMoneda().getCodigo());
		excepcionDuracionCf.setMenorOIgual(plazoDias);
		excepcionDuracionCf=excepcionDuracionCfDAO.obtenerExcepcionDuracionCf(excepcionDuracionCf);
		CostoFondeo costoFondeo=new CostoFondeo();
		if(excepcionDuracionCf!=null){
			costoFondeo.setCantidadDiasMaximo(excepcionDuracionCf.getAsignarPlazo());
		}else{
			costoFondeo.setCantidadDiasMaximo(plazoDias);
		}
		costoFondeo=costoFondeoDAO.obtenerCostoFondeo(costoFondeo);
		if(costoFondeo!=null){
			if(operacion.getMoneda().getCodigo().equals(Valor.CODIGO.PEN)){
				motor.setCf(costoFondeo.getTasaNacionalActiva());
			}else{
				motor.setCf(costoFondeo.getTasaDolarActiva());
			}
		}
		
		correrReglas(ruleBase, motor, "RAR");
		
		return motor;
	}

}
